/*
 *  $Id: Data.cs 1216 2010-11-26 17:35:07Z thenn.erannor $
 *  This file is a part of Ragima CCG.
 *  (C) 2008-2010 Ragima development group.
 *
 *  Licensed under the terms of the GNU GPL License version 2.
 *
 */

using System;
using System.Collections.Generic;

using AgateLib;
using AgateLib.AudioLib;
using AgateLib.DisplayLib;
using AgateLib.Geometry;

namespace Ragima {
    public static class Data {
        public static Surface LoadingBall;
        public static Surface LoadingText;

        [DataFile("shroud.png")]
        public static Surface Shroud;
        [DataFile("bg.jpg")]
        public static Surface Background;
        [DataFile("bg_blank.jpg")]
        public static Surface BackgroundBlank;
        [DataFile("connect_top.png")]
        public static Surface ConnectTop;
        [DataFile("connect_avatar.png")]
        public static Surface ConnectAvatar;
        [DataFile("connect_buttons.png")]
        public static UI.SpriteSurface ConnectButtons;
        [DataFile("frame.png")]
        public static Surface FrontPanel;
        [DataFile("dice.png")]
        public static Surface Dice;
        [DataFile("dice_eye.png")]
        public static Surface DiceEye;
        [DataFile("diceover.png")]
        public static Surface DiceOver;
        [DataFile("health_bars_overlay.png")]
        public static Surface HealthBarOverlay;
        [DataFile("meditation_bars.png")]
        public static Surface MeditationBars;
        [DataFile("cursors.png")]
        public static UI.CursorSurface Cursors;
        [DataFile("battle_notice.png")]
        public static Surface BattleNotice;
        [DataFile("scroll_empty.png")]
        public static Surface ScrollEmpty;
        [DataFile("scroll_full.png")]
        public static Surface ScrollFull;
        [DataFile("scroll_pointer.png")]
        public static Surface ScrollPointer;
        [DataFile("cardback.jpg")]
        public static Surface Cardback;
        [DataFile("card_disabled.png")]
        public static Surface CardDisabled;
        [DataFile("hourglass.png")]
        public static Surface CardDelay;
        [DataFile("border_green.png")]
        public static Surface CardSelect1;
        [DataFile("border_white.png")]
        public static Surface CardSelect2;
        [DataFile("phase_wait.jpg")]
        public static Surface PhaseWait;
        [DataFile("phase_defend.jpg")]
        public static Surface PhaseDefence;
        [DataFile("phase_attack.jpg")]
        public static Surface PhaseOffence;
        [DataFile("game_phases.jpg")]
        public static UI.SpriteSurface GamePhases;
        [DataFile("turns_advert.png")]
        public static UI.SpriteSurface TurnsAdvert;
        [DataFile("enemyturn_overlay.png")]
        public static Surface EnemyTurnOverlay;
        [DataFile("hint.png")]
        public static Surface Hint;
        [NumberFile("numbers_01.png", new int[] { 25, 15, 25, 25, 25, 25, 25, 25, 25, 25 })]
        public static NumberSurface Numbers01;
        [NumberFile("numbers_02_green.png", new int[] { 8, 7, 8, 8, 8, 8, 8, 8, 8, 8 })]
        public static NumberSurface Numbers02Green;
        [NumberFile("numbers_02_red.png", new int[] { 8, 7, 8, 8, 8, 8, 8, 8, 8, 8 })]
        public static NumberSurface Numbers02Red;
        [DataFile("hero_left.png")]
        public static Surface HeroLeft;
        [DataFile("hero_right.png")]
        public static Surface HeroRight;
        [DataFile("cards_left.png")]
        public static HoverableSurface ArrowLeft;
        [DataFile("cards_left_disabled.png")]
        public static Surface ArrowLeftDisabled;
        [DataFile("cards_right.png")]
        public static HoverableSurface ArrowRight;
        [DataFile("cards_right_disabled.png")]
        public static Surface ArrowRightDisabled;
        [DataFile("btn_use.png")]
        public static HoverableSurface ButtonUse;
        [DataFile("btn_end_turn.jpg")]
        public static HoverableSurface ButtonEndTurn;
        [DataFile("jog.png")]
        public static Surface Jog;
        [DataFile("arrow_d.png")]
        public static Surface AttackArrowDown;
        [DataFile("arrow_dl.png")]
        public static Surface AttackArrowDownLeft;
        [DataFile("arrow_dr.png")]
        public static Surface AttackArrowDownRight;
        [DataFile("arrow_u.png")]
        public static Surface AttackArrowUp;
        [DataFile("arrow_ul.png")]
        public static Surface AttackArrowUpLeft;
        [DataFile("arrow_ur.png")]
        public static Surface AttackArrowUpRight;
        [DataFile("mana_gain.png")]
        public static Surface ManaGain;

        [DataFile("tabs.png")]
        public static UI.SpriteSurface AllTabs;
        public static UI.Sprite[] Tabs;

        [DataFile("main_menu.png")]
        public static UI.SpriteSurface MenuButtons;

        [DataFile("status_icons.png")]
        public static UI.SpriteSurface StatusIcons;

        public static class DeckManager {
            [DataFile("cm_interface.jpg")]
            public static Surface Background;
            [DataFile("cm_buttons.png")]
            public static UI.SpriteSurface Buttons;
        }

        public static class Particles {
            [DataFile("Particles/ball.png")]
            public static Surface Ball;
            [DataFile("Particles/fire_01.png")]
            public static Surface Fire01;
            [DataFile("Particles/vlines_01.png")]
            public static Surface Vlines01;
            [DataFile("Particles/cloud_01.png")]
            public static Surface Cloud01;
            [DataFile("Particles/shine_01.png")]
            public static Surface Shine01;
        }

        public static class Fonts {
            [DataFile("main")]
            public static UI.Font Main;
            [DataFile("log")]
            public static UI.Font Log;
            [DataFile("notice")]
            public static UI.Font Notice;
            [DataFile("player_name")]
            public static UI.Font PlayerName;
            [DataFile("player_mana")]
            public static UI.Font PlayerMana;
            [DataFile("card_name")]
            public static UI.Font CardName;
            [DataFile("card_desc")]
            public static UI.Font CardDescription;
            [DataFile("card_desc_flavor")]
            public static UI.Font CardDescriptionFlavor;
            [DataFile("card_health")]
            public static UI.Font CardHealth;
        }

        public static class Sounds {
            public static SoundEventList Events;
        }

        public static class Musics {
            [DataFile("Mainmenu.ogg")]
            public static Music MainMenu;
        }

        private static DataResources _resources;

        public static void Initialize() {
            _resources = new DataResources();
            UI.ResourceManager.RegisterProvider(_resources);
            DrawClear();
            AgateFileProvider.Images.AddPath(Paths.Images);
            AgateFileProvider.Images.AddPath(Paths.Fonts);
            AgateFileProvider.Sounds.AddPath(Paths.Sounds);
            AgateFileProvider.Music.AddPath(Paths.Music);
            AgateFileProvider.Resources.AddPath(Paths.Data);
            LoadingBall = new Surface("loading.png");
            LoadingBall.DisplayAlignment = OriginAlignment.Center;
            LoadingText = new Surface("loading.jpg");
            LoadingText.DisplayAlignment = OriginAlignment.Center;
            CardManager.Initialize();
            Load();
            Display.PackAllSurfaces();
        }

        private static void Load() {
            DataLoader.RegisterType(typeof(Surface), LoadSurface);
            DataLoader.RegisterType(typeof(HoverableSurface), LoadHoverableSurface);
            DataLoader.RegisterType(typeof(UI.Font), UI.Font.LoadData);
            DataLoader.RegisterType(typeof(SoundBuffer), LoadSound);
            DataLoader.RegisterType(typeof(Music), LoadMusic);
            DataLoader.RegisterType(typeof(UI.SpriteSurface), UI.SpriteSurface.LoadData);
            DataLoader.RegisterType(typeof(UI.CursorSurface), UI.CursorSurface.LoadData);

            Sounds.Events = SoundEventList.Load("sound_events.xml");

            var loader = new DataLoader(typeof(Data), DoProgress, _resources);
            Loading.ProgressReset(loader.CountAllStatic + CardManager.CardsCount + ElementType.Count + Sounds.Events.Count);
            
            CardManager.Load();
            loader.LoadStatic();
            Sounds.Events.Load(DoProgress);
            
            foreach (var element in ElementType.AllElements) {
                element.LoadSurfaces();
                DoProgress();
            }
            
            Shroud.DisplayAlignment = OriginAlignment.Center;
            Dice.DisplayAlignment = OriginAlignment.Center;
            
            Tabs = Array.ConvertAll<string, UI.Sprite>(Constants.TabIdents, delegate(string id) { return AllTabs.GetSprite(id); });
            
            Loading.Wait();
        }
        private static void DoProgress() {
            Loading.ProgressInc();
        }
        private static object LoadSurface(string filename) {
            return new Surface(filename);
        }
        private static object LoadHoverableSurface(string filename) {
            return new HoverableSurface(filename);
        }
        private static object LoadSound(string filename) {
            return Application.Config.Sound.DriverEnabled ? new SoundBuffer(filename) : null;
        }
        private static object LoadMusic(string filename) {
            return Application.Config.Sound.DriverEnabled ? new Music(filename) : null;
        }

        private static void DrawClear() {
            Display.BeginFrame();
            Display.Clear();
            Display.EndFrame();
        }

        public static UI.Sprite GetTab(TabType tab) {
            return Tabs[(int) tab];
        }

        public static HoverableSurface GetArrow(bool dir) {
            return dir ? ArrowRight : ArrowLeft;
        }
        public static Surface GetArrowDisabled(bool dir) {
            return dir ? ArrowRightDisabled : ArrowLeftDisabled;
        }

        public static Surface GetAttackArrow(int @from, int to, bool dir) {
            if (dir) {
                if (@from == to)
                    return AttackArrowUp; else if (@from < to)
                    return AttackArrowUpRight;
                else
                    return AttackArrowUpLeft;
            } else {
                if (@from == to)
                    return AttackArrowDown; else if (@from < to)
                    return AttackArrowDownRight;
                else
                    return AttackArrowDownLeft;
            }
        }
    }

    public sealed class DataResources : IDataCollector, UI.IResourceProvider {
        private Dictionary<string, object> _data;

        public DataResources() {
            _data = new Dictionary<string, object>();
        }

        #region IDataCollector implementation
        void IDataCollector.Collect(string id, object data) {
            _data[id] = data;
        }
        #endregion

        #region IResourceProvider implementation
        T UI.IResourceProvider.GetResource<T>(string id) {
            object data;
            if (_data.TryGetValue(id, out data))
                return data as T;
            return null;
        }
        #endregion
    }
}
